/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.tue.nl.aa;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Based on: http://www.javapractices.com/topic/TopicAction.do?Id=62
 * @author waldo
 */
public class RandomProcessingTimes {

    private static int randomNumber;
    private static ArrayList<Integer> results;
    private static boolean useArgumentAsTime=false;
    /**
     * Example: /home/waldo/java/OrderedSchedulingAlgorithm/data/jobs_r.csv 1 10000 100000
     * @param args the command line arguments
     */
    public static void main(String[] args) throws Exception{
        try{
            if( args[4].equalsIgnoreCase("true") ) useArgumentAsTime=true;
        } catch( Exception e ){}
        RandomProcessingTimes.generateProcessingTimes(
                new File(args[0]),
                new File(args[0]+"r.csv"),
                Integer.parseInt(args[1]),
                Integer.parseInt(args[2]),
                Integer.parseInt(args[3])
        );
    }
    
    /**
     * 
     * @param start
     * @param end
     * @param amount
     * @param csvFile 
     */
    public static void generateProcessingTimes(File csvFile, File csvReverse, int start, int end, int amount){
        if( start < 1 ) throw new IllegalArgumentException("'start' argument must me greater than zero.");
        if( end<start ) throw new IllegalArgumentException("'end' argument must me greater than 'start' argument.");
        Random random = new Random();
        Writer resultsWriter=null;
        try {
            resultsWriter = new BufferedWriter(new FileWriter(csvFile));
            results = new ArrayList<Integer>();
            if( !useArgumentAsTime ) for( int idx = 0; idx < amount; idx++ ){
                getRandomInteger(start, end, random);
                results.add(randomNumber);
                resultsWriter.write( results.get(idx) + "\n" );
            } else {
                //amount is the time
                int time=0, total=0;
                do{
                    getRandomInteger(start, end, random);
                    time+=randomNumber;
                    if( time<amount ){
                        total+=randomNumber;
                        results.add( randomNumber );
                    }
                } while( time<amount );
                total=amount-total;
                if( total>0 ) results.add( total );
                for( int i : results ) resultsWriter.write( i + "\n" );
            }
        } catch (IOException ex) {
            Logger.getLogger(RandomProcessingTimes.class.getName()).log(Level.SEVERE, ex.toString(), ex);
        } finally {
            try {
                resultsWriter.close();
            } catch (IOException ex) {
                Logger.getLogger(RandomProcessingTimes.class.getName()).log(Level.SEVERE, ex.toString(), ex);
            }
        }
//        try{
//            resultsWriter = new BufferedWriter(new FileWriter(csvReverse));
//            for( int idx=results.size()-1; idx>=0; idx-- ){
//                resultsWriter.write( results.get(idx) + "\n" );
//            }
//        } catch (IOException ex) {
//            Logger.getLogger(RandomProcessingTimes.class.getName()).log(Level.SEVERE, ex.toString(), ex);
//        } finally {
//            try {
//                resultsWriter.close();
//            } catch (IOException ex) {
//                Logger.getLogger(RandomProcessingTimes.class.getName()).log(Level.SEVERE, ex.toString(), ex);
//            }
//        }
    }
    
    /**
     * 
     * @param aStart
     * @param aEnd
     * @param aRandom 
     */
    private static void getRandomInteger(int aStart, int aEnd, Random aRandom){
        if ( aStart > aEnd ) throw new IllegalArgumentException("Start cannot exceed End.");
        //get the range, casting to long to avoid overflow problems
        long range = (long)aEnd - (long)aStart + 1;
        // compute a fraction of the range, 0 <= frac < range
        long fraction = (long)(range * aRandom.nextDouble());
        randomNumber =  (int)(fraction + aStart);
    }

}
